package com.rh.manage.service;

import com.rh.manage.config.ReadUserConfig;
import com.rh.manage.exception.ApplicationException;
import com.rh.manage.exception.ErrorCodeEnum;
import com.rh.manage.model.UserConfig;
import org.eclipse.jgit.api.AddCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.PullCommand;
import org.eclipse.jgit.api.PushCommand;
import org.eclipse.jgit.api.errors.EmptyCommitException;
import org.eclipse.jgit.merge.MergeStrategy;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.File;

@Component
public class GitService {

    @Autowired
    private ReadUserConfig readUserConfig;
    private Git git;

    @PostConstruct
    public void init() throws Exception {
        UserConfig userConfig = readUserConfig.getUserConfig();
        if (userConfig == null) {
            return;
        }
        git = Git.open(new File(userConfig.getGitProjectPath()));
    }

    /**
     * 更新
     */
    public void pullOpt() {
        add();
        commit();
        try {
            pull();
        } catch (Exception e) {
            reset(); // 自动合并失败时, 删除合并信息, 方便手动合并
            throw e;
        }
    }

    /**
     * 推送
     */
    public void pushOpt() {
        add();
        commit();
        try {
            pull();
            push();
        } catch (Exception e) {
            reset(); // 自动合并失败时, 删除合并信息, 方便手动合并
            throw e;
        }
    }

    @PreDestroy
    public void destroy() {
        if (git == null) {
            return;
        }
        git.close();
    }

    private void add() throws ApplicationException {
        if (git == null) {
            return;
        }
        AddCommand add = git.add().addFilepattern(".");
        try {
            add.call();
        } catch (Exception e) {
            throw new ApplicationException(ErrorCodeEnum.GIT_ADD_OPERATION_FAILED, e);
        }
    }

    private void commit() throws ApplicationException {
        if (git == null) {
            return;
        }
        try {
            git.commit().setMessage("update").setAllowEmpty(false).call();
        } catch (EmptyCommitException e) {
            // 没有要提交的内容
        } catch (Exception e) {
            throw new ApplicationException(ErrorCodeEnum.COMMIT_OPERATION_FAILED, e);
        }
    }

    private void pull() throws ApplicationException {
        if (git == null) {
            return;
        }
        try {
            // 不带密码更新
            PullCommand pull = git.pull();
            pull.setStrategy(MergeStrategy.SIMPLE_TWO_WAY_IN_CORE)
                    .setCredentialsProvider(new UsernamePasswordCredentialsProvider("1340215221@qq.com", "rh67505509aru"))
                    .call();
        } catch (Exception e) {
            throw new ApplicationException(ErrorCodeEnum.PULL_OPERATION_FAILED, e);
        }
    }

    private void reset() {
        if (git == null) {
            return;
        }
        try {
            git.reset().call();
        } catch (Exception e) {
            throw new ApplicationException(ErrorCodeEnum.RESET_OPERATION_FAILED, e);
        }
    }

    private void push() {
        if (git == null) {
            return;
        }
        try {
            PushCommand push = git.push();
            if (true) {
                // 添加提交密码
                push.setCredentialsProvider(new UsernamePasswordCredentialsProvider("1340215221@qq.com", "rh67505509aru"));
            }
            push.setTimeout(60);
            push.call();
        } catch (Exception e) {
            throw new ApplicationException(ErrorCodeEnum.GIT_PUSH_FAILED, e);
        }
    }
}
